<?php
namespace app\common\modelMethod;
use think\facade\Cache;

trait Order
{
	/**
    * 发放订单收益- 包含购买者获得礼包及积分，上级获得收益等
    * @param $order
    * @return bool
    */
    public static function grantOrderProfit($orderKey)
    {
    	if(is_string($orderKey) || is_numeric($orderKey)){
    		$order = self::getOrderDetail($orderKey);
    	}else{
    		$order = $orderKey;
    	}
    	
    	$shopId = $order['shop_id'];
    	$orderUid = $order['uid'];
    	$orderNo = $order['order_no'];
    	
    	//数据集
    	$reappeGroup = $order->info['reappeGroup'];
		
		//TODO 0.会员升级
		$res = model('UserVip')->upgrade($orderUid);
		
    	//TODO 1.用户获得积分
    	$res = model('User')->addIntegral($orderUid,$reappeGroup['gainIntegral'],$orderNo);
		if(!$res){
			throw new \think\Exception("发放积分错误！");
		}
		
    	//TODO 2.用户获得优惠券
    	foreach($reappeGroup['gifts'] as $key => $value){
    		foreach($value['gift'] as $k => $val){
    			if($val['coupon_id']){
    				for ($i=1; $i<=$val['coupon_num']; $i++){
	        			$res = $res && model('coupon')->grant($val['coupon_id'],$orderUid);
	    			}
    			}
    		}
    	}
		if(!$res){
			//throw new \think\Exception("发放优惠券错误 : ".model('coupon')->errorInfo);
		}
		
    	//TODO 3.推荐人获得佣金
		$brokerage = model('User')->backOrderBrokerage($order);
		if($brokerage === false){
			throw new \think\Exception("发放佣金错误！");
		}
		
		//TODO 4.店铺获得收入
		if( !$res = model('Shop')->orderIncome($shopId,$order) ){
			throw new \think\Exception("店铺获得余额错误！");
		}

		$order->is_brokerage = 1;
		if( !$res = $res && $order->save() ){
			throw new \think\Exception("异常错误，请联系管理员！");
		}
		
    	return true;
    }
	
	/**
     * 自动根据订单编号，订单id，订单唯一编号  获取订单
     * @param $uid
     * @param $key
     */
    public static function getOrderDetail($key,$uid=''){
    	$model = self::where('order_no|id', $key);
    	$model =$model->where('is_del', 0);
    	$model =$model->where('is_system_del', 0);
        if($uid) $model =$model->where('uid',$uid);
    	if ( !$order=$model->find() ){
        	throw new \think\Exception("订单不存在！");
        }
        return self::tidyOrder($order);
    }
    
	
	/**获取订单价格组信息
     * @param $cartInfo
     * @return array
     */
    private static function getPriceGroup($userInfo,$cartInfo,$addressInfo)
    {
        //商品成本总价
        $totalCostPrice = self::getOrderSumPrice($cartInfo, 'cost_price');
      	//商品原价-总价
        $totalOldPrice = self::getOrderSumPrice($cartInfo, 'price');
		//商品销售总价 - 已算会员折扣
        $totalSalePrice = self::getOrderSumPrice($cartInfo, 'sale_price');
        //商品销售总价 - 未算会员折扣
        $totalSaleOldPrice = self::getOrderSumPrice($cartInfo, 'sale_old_price');
        //邮费
    	$freightPrice = model('ShopFreight')->getCartPostage($cartInfo,$addressInfo['province']);
		//订单总金额					
        $totalPrice = $totalSalePrice;		
        //抵扣
      	$deductPrice = 0;
       	//付款
      	$payPrice = $totalPrice - $deductPrice;
		//返回 	
        return compact(
        	'totalCostPrice','totalOldPrice', 'totalSalePrice','totalSaleOldPrice',
        	'freightPrice', 'totalPrice','deductPrice','payPrice'
		);
    }
    
    /**获取返现组信息
     * @param $cartInfo
     * @return array
     */
    private static function getReappeGroup($cartInfo,$uid)
    {
    	$gifts = [];
    	foreach( $cartInfo as $key => $val ){
    		$num = $val['cart_num'];
    		$gift = [];
    		$gift['goods_id'] = $val['goods_id'];
    		$gift['goods_name'] = $val['goods']['goods_name'];
    		$subQuery = model('coupon_user')
			    ->field('parent_id,count(id) as receive_num')
				->group("parent_id")
				->where("uid",$uid)
			    ->buildSql();
    		$gift['gift'] = model('GoodsSpecsGift')->alias('a')
    			->leftJoin('xw_coupon b',"a.coupon_id = b.id")
    			->leftJoin("$subQuery c",'b.id = c.parent_id')
				->field("
					a.id,
					a.name,
					a.gift_name,
					(ifnull(a.integral,0) * $num) as integral,
					(ifnull(a.gift_num,0) * $num) as gift_num,
					b.id as coupon_id,
					b.name as coupon_name,
					if(	(ifnull(a.coupon_num,0) * $num) <= b.remain_num,
						if( b.can_num > 0 and (a.coupon_num * $num) > (b.can_num - ifnull(c.receive_num,0)), 
							b.can_num - ifnull(c.receive_num,0) , a.coupon_num * $num
						),
						if( b.can_num > 0 and b.remain_num > (b.can_num - ifnull(c.receive_num,0)), 
							b.can_num - ifnull(c.receive_num,0) , b.remain_num
						)
					) as coupon_num,
					b.price as coupon_price,
					b.remark as coupon_remark
				")
				->where('a.specs_id',$val['specs_id'])
				->select();
				
			$gifts[] = $gift;
    	}
    	
    	//TODO 获得积分
        //TODO 获得优惠券
        $gainIntegral = 0;
        $couponNum = 0;
        $couponIds = [];
        foreach($gifts as $key => $value){
        	foreach($value['gift'] as $k => $gift){
        		$gainIntegral += (float)$gift['integral'];
        		$couponNum += (int)$gift['coupon_num'];
        		$couponIds[] = (int)$gift['coupon_id'];
        	}
        }
        
        $msg = "购买后可获得礼包！";
        return compact('gifts','gainIntegral','couponNum','msg');
    }
    
    
    
	/**获取订单积分信息
     * @param $cartInfo
     * @return array
     */
    private static function getIntegralInfo($userInfo,$cartInfo)
    {
    	$shop_id = $userInfo['shop_id'];	  		//店铺
    	$userIntegral =  $userInfo['integral'];  	//当前用户剩余积分
    	
    	//积分比列 1000积分等于多少钱，换成1块钱等于多少积分	
    	$scale = model('ShopParam')->where('shop_id',$shop_id)->value('integral_scale') ?: 0;
    	$inteBili = $scale <= 0 ? 0 : 1000 / $scale;
	
		$deductPrice = 0;
		$useIntegral = 0;
		
		//循环购物车每个商品计算可使用积分及抵扣价格
		foreach($cartInfo as $key => $val){
			if( $val->goods['is_integral_gift'] === 1 ){ 
				$deductPrice = $val->goods['sale_old_price'];
				$useIntegral = $val->goods['use_integral'];
				break;     //积分礼品 终止循环
			}else{
				//当前商品可使用积分
				$goodsIntegral = $val->goods['use_integral'] * $val['cart_num'];
				//当前商品应总使用积分
				$answerUseIntegral = $val->goods['sale_price'] * $val['cart_num'] * $inteBili;
				//当前商品实际使用积分
				$actualIntegral = $userIntegral >= $answerUseIntegral ? $answerUseIntegral : $userIntegral;
				$actualIntegral = $actualIntegral > $goodsIntegral ? $goodsIntegral : $actualIntegral;
				//结果
				$deductPrice = round($deductPrice + bcdiv($actualIntegral, $inteBili, 2) , 2);
				$useIntegral = round( $useIntegral + $actualIntegral , 2);
				$userIntegral = round(  $userIntegral - $actualIntegral , 2);
			}
		}
		
		$msg = "共使用".$useIntegral."积分抵扣".$deductPrice."元";
		
        return compact( 'useIntegral','inteBili','deductPrice','msg');
    }
    
    
    /**获取订单赠送金额可抵扣信息
     * @param $cartInfo
     * @return array
     */
    private static function getDeductBalance($userInfo,$cartInfo)
    {
    	$userGiftBalance = $userInfo['balance_gift'];  	//当前用户剩余赠送余额
    	$deductPrice = 0;
		//循环购物车每个商品计算可抵扣余额及抵扣价格
		foreach($cartInfo as $key => $val){
			$goodsUsePrice = $val->goods['use_price'] * $val['cart_num'];
			if( $goodsUsePrice > 0 && $userGiftBalance > 0 ){
				if( $userGiftBalance >= $goodsUsePrice ){
					$deductPrice =  round( $deductPrice + $goodsUsePrice, 2);
				}else{
					$deductPrice = $userGiftBalance;
				}
				$userGiftBalance =  round( $userGiftBalance - $deductPrice,2);
			}
		}
		$msg = "共使用".$deductPrice."赠送余额抵扣".$deductPrice."元";
        return compact( 'userGiftBalance', 'deductPrice','msg');
    }
    
    
     /**
     * 获取订单状态购物车等信息
     * @param $order
     * @param bool $detail 是否获取订单购物车详情
     * @param bool $isPic 是否获取订单状态图片
     * @return mixed
     */
    public static function tidyOrder($order, $detail = false){
        if ($detail == true && isset($order['id'])) {
            $cartInfo = model('OrderCart')::where('order_id', $order['id'])->column('cart_info') ?: [];
            $info = [];
            foreach ($cartInfo as $k => $cart) {
                $cart = json_decode($cart, true);
                array_push($info, $cart);
                unset($cart);
            }
            $order['cartInfo'] = $info;
        }
		
		// 计算状态文本
        $status = [];
      	if (!$order['is_pay']) {
            $status['_type'] = 0;
            $status['_title'] = '未支付';
			$order_cancel_time = 	getSystem("buess_order_pay_time") ?? 0;
			if(!$order_cancel_time){
				$status['_msg'] = '请前往完成支付!';
			}else{
				$time = bcadd(strtotime($order['add_time']), $order_cancel_time, 0);
            	$status['_msg'] = '请在' . date('m月d日 H:i:s', $time) . '前完成支付!';
			}
        } 
        elseif ($order['refund_status'] == -1) {
            $status['_type'] = -1;
            $status['_title'] = '申请退款未通过';
            $status['_msg'] = '原因：'.$order['refund_reason'];
        } 
        elseif ($order['refund_status'] == 1) {
            $status['_type'] = -1;
            $status['_title'] = '申请退款中';
            $status['_msg'] = '商家审核中,请耐心等待';
        } 
        elseif ($order['refund_status'] == 2 && $order['status'] == 0) {
            $status['_type'] = -2;
            $status['_title'] = '未发货,已退款';
            $status['_msg'] = '商品库存不足！';
        } 
        elseif ($order['refund_status'] == 2) {
            $status['_type'] = -2;
            $status['_title'] = '已退款';
            $status['_msg'] = '已为您退款,感谢您的支持';
        } 
        elseif ($order['status'] == -2) {
            $status['_type'] = -2;
            $status['_title'] = '已取消';
            $status['_msg'] ='订单已被取消';
        }
		elseif ($order['is_pay'] == 2) {
            $status['_type'] = 1;
            $status['_title'] = '部分支付';
            $status['_msg'] ='已支付定金，确认定制稿后请尽快支付尾款！';
        }
        elseif ($order['status'] == 0 && $order['is_pay'] == 1) {
            $status['_type'] = 1;
            $status['_title'] = '待发货';
            $status['_msg'] ='已支付,待商家发货,请耐心等待';
        } 
        elseif ($order['status'] == 1) {
            $status['_type'] = 2;
            $status['_title'] = '待收货';
			$order_receive_time = getSystem("buess_order_receive_time") ?? 0;
			if(!$order_receive_time){
				$status['_msg'] = $order['delivery_time']. '已发货';
			}else{
				$time = bcadd(strtotime($order['delivery_time']), $order_receive_time, 0);
            	$status['_msg'] = '将于' . date('m月d日 H:i:s', $time) . '后自动确认收货!';
			}
        } 
        elseif ($order['status'] == 2) {
            $status['_type'] = 3;
            $status['_title'] = '待评价';
            $status['_msg'] = '已收货,快去评价一下吧';
        } 
        elseif ($order['status'] == 3) {
            $status['_type'] = 4;
            $status['_title'] = '交易完成';
            $status['_msg'] = '交易完成,感谢您的支持';
        }
        if (isset($order['pay_type'])){
        	$status['_payType'] = self::$payType[$order['pay_type']] ?: '其他方式';
        }
        if (isset($order['delivery_type'])){
        	$status['_deliveryType'] = self::$deliveryType[$order['delivery_type']] ?: '其他方式';
        }
        $order['_status'] = $status;
        return $order;
    }
    
    
    /**
     * 未支付订单超过预设时间回退所有,如果不设置未支付过期时间，将不取消订单
     * @param $time 预设时间
     * @param $order 订单详情
     */
    protected static function regressionAll($time, $order)
    {
        if ($time == 0) return true;
        if ((strtotime($order['add_time']) + $time) < time()) {
            $res1 = self::regressionStock($order);
            $res2 = self::regressionIntegral($order);
            $res3 = self::regressionCoupon($order);
            $res = $res1 && $res2 && $res3;
            if ($res) $res = false !== self::where('id', $order['id'])->update([
            		'is_del' => 1, 
            		'admin_remark' => '订单未支付已超过系统预设时间,自动关闭'
            ]);
            unset($res1, $res2, $res3);
            return $res;
        } else
            return true;
    }
    
    /**
     * 回退积分
     * @param $order 订单信息
     * @return bool
     */
    public static function regressionIntegral($order)
    {
        if ($order['is_pay'] || $order['status'] == -2 || $order['is_del']) return true;
        $integral = $order->info['integralInfo'];
        if ($integral['useIntegral'] <= 0) return true;
        if ( (int)$order['status'] != -2 && (int)$order['refund_status'] != 2 && $order['is_pay']==1){
        	return true;
        }
        $res = model('User')->addIntegral($order['uid'],$integral['useIntegral'],$order['order_no'],3);
        if (!$res) {
            throw new \think\Exception('回退积分失败!');
        }
        return true;
    }

    /**
     * 回退库存和销量
     * @param $order 订单信息
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function regressionStock($order)
    {
        if ($order['is_pay'] || $order['status'] == -2 || $order['is_del']) return true;
        $res = true;
        $cartInfo = $order->info['cartInfo'];
        foreach ($cartInfo as $cart) {
            if ( $cart['seckill_id'] ) {
            	$res = $res && model('GoodsSeckill')->incStock($cart['seckill_id'],$cart['cart_num']);
            } else {
             	model('GoodsSpecs')->incStock($cart['specs_id'],$order['shop_id'],$cart['cart_num']);
			}
        }
        return $res;
    }

    /**
     * 回退优惠卷
     * @param $order 订单信息
     * @return bool
     */
    public static function regressionCoupon($order)
    {
        if ($order['is_pay'] || $order['status'] == -2 || $order['is_del']) return true;
        $res = true;
        if ( $order['coupon_id'] ) {
            $res = $res && false !== model('CouponUser')
            	->where('id', $order['coupon_id'])
            	->where('uid', $order['uid'])
            	->update(['status' => 0, 'use_time' => '']);
        }
        return $res;
    }
    
	
	/**获取某个字段总金额
     * @param $cartInfo
     * @param $key 键名
     * @return int|string
     */
    public static function getOrderSumPrice($cartInfo, $key = 'price',$num=2)
    {
        $sumPrice = 0;
        foreach ($cartInfo as $cart) {
            $sumPrice = bcadd($sumPrice, bcmul($cart['cart_num'], $cart[$key], 2), $num);
        }
        return $sumPrice;
    }
    
    
    /**
     * 缓存订单信息
     * @param $uid
     * @param array $orderInfo
     * @param int $cacheTime
     */
    public static function cacheOrderInfo($uid,$orderInfo,$cacheTime = 600)
    {
        $key = md5(get_uuid().'_'.json_encode($orderInfo).'_'.$uid);
        Cache::set('user_order_' .  $key, $orderInfo, $cacheTime);
        return $key;
    }

    /**
     * 获取订单缓存信息
     * @param $uid
     * @param $key
     * @return mixed|null
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public static function getCacheOrderInfo($key)
    {
        $cacheName = 'user_order_' . $key;
        if (!Cache::has($cacheName)) return null;
        return Cache::get($cacheName);
    }

    /**
     * 删除订单缓存
     * @param $uid
     * @param $key
     */
    public static function clearCacheOrderInfo( $key)
    {
        Cache::set('user_order_' . $key,'');
    }
    
}